using System;
using System.Collections.Generic;
using System.Diagnostics;
#if NETFX_CORE
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
#else
using System.Windows;
#if SILVERLIGHT
using System.Windows.Controls;
#endif
#endif

namespace FreshMeat.Xaml
{
   public class FocusContext
   {
      readonly List<FocusContext> contexts;
      readonly WeakReference weakWhoHadIt;
      readonly WeakReference weakWhoGotIt;
      bool irrelevant;

#if !SILVERLIGHT && !NETFX_CORE
      public FocusContext(List<FocusContext> contexts, UIElement whoHadIt, UIElement whoGotIt)
#else
      public FocusContext(List<FocusContext> contexts, Control whoHadIt, Control whoGotIt)
#endif
      {
         this.contexts = contexts;
         weakWhoHadIt = new WeakReference(whoHadIt);
         weakWhoGotIt = new WeakReference(whoGotIt);

         contexts.Add(this);
      }

      public void Restore()
      {
         // First get whether it's relevant.
         var wasRelevant = IsRelevant(FocusHelper.FocusedElement);

         // Then make it not relevant and remove it from the list.  Removing it is
         // critical because SetFocus will ignore calls while there are temporary
         // contexts in the list.
         irrelevant = true;
         contexts.Remove(this);

         if (wasRelevant)
         {
#if !SILVERLIGHT && !NETFX_CORE
            var whoHadIt = weakWhoHadIt.Target as UIElement;
#else
            var whoHadIt = weakWhoHadIt.Target as Control;
#endif
            Trace.TraceInformation("FocusHelper restoring previous focus context");
            FocusHelper.SetFocus(whoHadIt);
         }
         else
         {
            Trace.TraceInformation("FocusHelper not restoring previous focus context because it no longer applies");
         }
      }

      public bool IsRelevant(UIElement focusedElement)
      {
         if (irrelevant)
            return false;

#if !SILVERLIGHT && !NETFX_CORE
         var whoGotIt = weakWhoGotIt.Target as UIElement;
#else
         var whoGotIt = weakWhoGotIt.Target as Control;
#endif
         irrelevant = focusedElement != whoGotIt;
         return !irrelevant;
      }
   }
}